package com.litchi.tutor.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.litchi.tutor.common.cons.RedisKey;
import com.litchi.tutor.common.entity.Teacher;
import com.litchi.tutor.common.entity.User;
import com.litchi.tutor.common.entity.UserView;
import com.litchi.tutor.common.util.JwtUtil;
import com.litchi.tutor.common.util.QRCodeUtil;
import com.litchi.tutor.common.util.RedisUtil;
import com.litchi.tutor.common.util.WxUtil;
import com.litchi.tutor.common.vo.LoginResp;
import com.litchi.tutor.config.Properties;
import com.litchi.tutor.mapper.TeacherMapper;
import com.litchi.tutor.mapper.UserMapper;
import com.litchi.tutor.service.ConfigService;
import com.litchi.tutor.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Date;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    Properties properties;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private QRCodeUtil qrCodeUtil;

    @Autowired
    private ConfigService configService;

    @Autowired
    private TeacherMapper teacherMapper;

    /**
     * 根据code获取用户信息（登录）
     * @param code
     * @return
     */
    @Override
    @Transactional
    public LoginResp loginByCode(String code) throws Exception {
        String appId = Properties.APP_ID;
        String appSecret = Properties.APP_SECRET;

        // 先获取access_id和openid
        String accessTokenAndOpenId = WxUtil.getAccessTokenAndOpenId(code, appId, appSecret);
        JSONObject jsonObject = JSONObject.parseObject(accessTokenAndOpenId);
        String access_token = jsonObject.getString("access_token");
        String openId = jsonObject.getString("openid");


        String userjson = WxUtil.getUserInfo(access_token, openId);
        User userInfo = JSONObject.parseObject(userjson, User.class);

        User user = getByOpenId(openId);
        LocalDateTime now = LocalDateTime.now();
        // 若没查到则注册
        if (user == null) {
            user = new User();
            BeanUtils.copyProperties(userInfo, user);
            // userId
            String nextUserId = configService.getConfigValueByKey(Properties.CONFIG_KEY);

            // 生成文件名
            Long startTs = System.currentTimeMillis(); // 当前时间戳
            StringBuffer stringBuffer = new StringBuffer(Properties.IMAGES_URL_PRE);
            StringBuffer qrcode = new StringBuffer("/qrcode").append("/").append(nextUserId).append(startTs).append(".jpg");   // /qrcode/3333333331635232610168.jpg
            StringBuffer qrcodeUrl = stringBuffer.append(qrcode);   // /data/litchi-staging/assets/qrcode/3333333331635232610168.jpg

            // 上传二维码图片
            boolean b = qrCodeUtil.orCode("http://m.lzjiajiaoshe.com/resume/:", nextUserId, String.valueOf(qrcodeUrl));
            if (b) {
                user.setQrcodeUrl(String.valueOf(qrcode));
            }

            user.setUserid(nextUserId);
            user.setOpenid(openId);
            user.setCreateTime(now);
            user.setUpdateTime(now);
            user.setLastLoginTime(now);
            user.setLoginCount(1);
            save(user);
        }
        else {
            // 注册过的用户，如果修改过用户信息就不存入最新的微信用户信息，否则存入最新的微信用户信息
            // update_time > last_login_time
            if (user.getUpdateTime().isEqual(user.getLastLoginTime())) {
                // 没修改过，存入最新数据
                BeanUtils.copyProperties(userInfo, user);
                user.setOpenid(openId);
            }
            user.setUpdateTime(now);
            user.setLastLoginTime(now);
            user.setLoginCount(user.getLoginCount() + 1);
            updateById(user);
        }
        // 生成token
        UserView userView = new UserView();
        BeanUtils.copyProperties(user, userView);
        userView.setToken(JwtUtil.generate(user.getId(), DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, 30)));
        redisUtil.set(RedisKey.USER_TOKEN_PRE + user.getId(), userView);

        LoginResp loginResp = new LoginResp();
        BeanUtils.copyProperties(user, loginResp);
        loginResp.setToken(userView.getToken());
        return loginResp;
    }

    /**
     * 根据openId获取用户信息（登录）
     * @param openId
     * @return
     */
    @Override
    public LoginResp loginByOpenId(String openId) {
        User user = this.getOne(new QueryWrapper<User>().eq("openid", openId));
        LocalDateTime now = LocalDateTime.now();
        user.setLoginCount(user.getLoginCount() + 1);
        user.setUpdateTime(now);
        user.setLastLoginTime(now);
        LoginResp loginResp = new LoginResp();
        BeanUtils.copyProperties(user, loginResp);
        return loginResp;
    }

    /**
     * 根据openid查询user
     * @param openId
     * @return
     */
    public User getByOpenId(String openId) {
        User user = this.getOne(new QueryWrapper<User>().eq("openid", openId));
        return user;
    }

    /**
     * 查询用户信息
     * @param userid
     * @return
     */
    @Override
    public User getUserInfo(String userid, HttpServletRequest request) {
        if (userid != null ) {
            User userid1 = getOne(new QueryWrapper<User>().eq("userid", userid));
            return userid1;
        } else {
            String token = request.getHeader("Authorization");
            Integer id = JwtUtil.getId(token);
            User id1 = getOne(new QueryWrapper<User>().eq("id", id));
            return id1;
        }
    }

    @Override
    public void updateRole(Integer role, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Integer id = JwtUtil.getId(token);
        User user = getOne(new QueryWrapper<User>().eq("id", id));
        System.out.println(user);
        if (user.getRole() == 0) {
            user.setRole(role);
            update(user, null);
        }
        else {
            throw new RuntimeException("只能更改一次");
        }
    }

    @Override
    public void updateRoleByAdmin(Integer userId, User user) {
        User userInfo = getOne(new QueryWrapper<User>().eq("userId", userId));
        if (userInfo != null) {
            update(user, null);
        } else {
            throw new RuntimeException("查无此用户");
        }
    }

    @Override
    public void deleteRole(Integer userId) {
        User userid = getOne(new QueryWrapper<User>().eq("userid", userId));
        if (userid != null) {
            userid.setRole(0);
            update(userid,null);
        } else {
            throw new RuntimeException("查无此用户");
        }

    }

    @Override
    public void deleteUser(Integer userId, HttpServletRequest request) {
        if (userId == null) {
            String token = request.getHeader("Authorization");
            Integer id = JwtUtil.getId(token);
            redisUtil.deleteKey(RedisKey.USER_TOKEN_PRE + id);
            // 删除简历
            User byId = getById(id);
            teacherMapper.delete(new QueryWrapper<Teacher>().eq("userid", byId.getUserid()));
            removeById(id);
        } else {
            User userid = getOne(new QueryWrapper<User>().eq("userid", userId));
            redisUtil.deleteKey(RedisKey.USER_TOKEN_PRE + userid.getId());
            // 删除简历
            teacherMapper.delete(new QueryWrapper<Teacher>().eq("userid", userId));
            remove(new QueryWrapper<User>().eq("userid", userId));
        }
    }
}
